package com.xiaozhi.java.ai.langchain4j.controller;

import com.xiaozhi.java.ai.langchain4j.assistant.XiaozhiAgentMCP;
import com.xiaozhi.java.ai.langchain4j.bean.ChatForm;
import com.xiaozhi.java.ai.langchain4j.tools.AppointmentTools;
import dev.langchain4j.community.model.dashscope.QwenStreamingChatModel;
import dev.langchain4j.mcp.McpToolProvider;
import dev.langchain4j.mcp.client.DefaultMcpClient;
import dev.langchain4j.mcp.client.McpClient;
import dev.langchain4j.mcp.client.transport.McpTransport;
import dev.langchain4j.mcp.client.transport.http.HttpMcpTransport;
import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.service.AiServices;
import dev.langchain4j.service.tool.ToolProvider;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Flux;

import java.util.List;
import java.util.Map;

@Tag(name = "硅谷小智MCP版")
@RestController
@RequestMapping("/xiaozhi-mcp")
public class XiaozhiMCPController {

    @Autowired
    private QwenStreamingChatModel qwenStreamingChatModel;

    @Autowired
    private ChatMemoryProvider chatMemoryProviderXiaozhi;

    @Autowired
    private AppointmentTools appointmentTools;

    @Autowired
    private ContentRetriever contentRetrieverXiaozhiPincone;


    @Operation(summary = "对话")
    @PostMapping(value = "/chat", produces = "text/stream;charset=utf-8")
    public Flux<String> chat(@RequestBody ChatForm chatForm){
        //首先需要一个 MCP 传输层实例
        //使用 stdio 启动 NPM 包中的服务器作为子进程

//        高德地图的mcp传输层：
        McpTransport transport = new StdioMcpTransport.Builder()
                .command(List.of(
                        "C:\\Program Files\\nodejs\\npx.cmd",
                        "-y",
                        "@amap/amap-maps-mcp-server"
                ))
                .environment(Map.of("AMAP_MAPS_API_KEY", System.getenv("AMAP_MAPS_API_KEY")))
                .logEvents(true) // 可选，用于在日志中显示通信内容
                .build();

        //通过传输层创建 MCP 客户端:高德地图
        McpClient mcpClient = new DefaultMcpClient.Builder()
                .transport(transport)
                .build();


        //最后通过客户端创建工具提供器
        ToolProvider toolProvider = McpToolProvider.builder()
                .mcpClients(List.of(mcpClient)) // 支持同时使用多个客户端
                //若设置 `failIfOneServerFails(true)`，则任意服务器失败时工具提供器将抛出异常；
                // 可选，默认 `false` 会忽略单服务器错误，继续使用其他服务器。
                .failIfOneServerFails(false)
                .build();

        //将工具提供器绑定到 AI 服务
        XiaozhiAgentMCP xiaozhiAgentMCP = AiServices.builder(XiaozhiAgentMCP.class)
                .streamingChatLanguageModel(qwenStreamingChatModel)
                .chatMemoryProvider(chatMemoryProviderXiaozhi)
                .tools(appointmentTools)
                .toolProvider(toolProvider) //在本Controller层封装的toolProvider（高德地图mcp）并没有捆绑到XiaozhiAgentMCP上，
                // 其他Controller调用XiaozhiAgentMCP是使用不到该高德地图mcp的
                .contentRetriever(contentRetrieverXiaozhiPincone)
                .build();
        return xiaozhiAgentMCP.chat(chatForm.getMemoryId(), chatForm.getMessage());
    }
}